﻿function Language(data) {
    this.Name = ko.observable(data);
}

function TogglePreloader(selector1, selector2) {
    var el1 = $(selector1);
    var el2 = $(selector2);

    if (el1.hasClass('hide')) {
        el1.removeClass('hide');
    }
    else {
        el1.addClass('hide');
    }

    if (el2.hasClass('hide')) {
        el2.removeClass('hide');
    }
    else {
        el2.addClass('hide');
    }
}

//control visibility, give element focus, and select the contents (in order)
ko.bindingHandlers.visibleAndSelect = {
    update: function (element, valueAccessor) {
        ko.bindingHandlers.visible.update(element, valueAccessor);
        if (valueAccessor()) {
            setTimeout(function () {
                $(element).focus().select();
            }, 0); //new tasks are not in DOM yet
        }
    }
}

ko.bindingHandlers.sortableList = {
    init: function (element, valueAccessor, allBindingsAccessor, data, context) {
        var options = ko.utils.unwrapObservable(valueAccessor());
        $(element).data("sortList", options.list || valueAccessor()); //attach meta-data
        $(element).sortable({
            update: function (event, ui) {
                var item = ui.item.data("sortItem");
                if (item) {
                    //identify parents
                    var originalParent = ui.item.data("parentList");
                    var newParent = ui.item.parent().data("sortList");
                    //figure out its new position
                    var position = ko.utils.arrayIndexOf(ui.item.parent().children(), ui.item[0]);
                    if (position >= 0) {
                        originalParent.remove(item);

                        if (self.newSitePageDefinition().length == 0) {
                            self.addPageGroupDefinition();
                        }

                        newParent.splice(position, 0, item);
                    }
                    ui.item.remove();
                }
            },
            connectWith: '.container'
        });
        return ko.bindingHandlers.template.init.apply(this, arguments);
    },
    update: function (element, valueAccessor, allBindingsAccessor, data, context) {
        var options = ko.utils.unwrapObservable(valueAccessor()),
            newOptions = {};

        //build our options to pass to the template engine
        if (options.list) {
            newOptions.foreach = options.list;
            newOptions.name = options.tmpl;
            newOptions.includeDestroyed = options.includeDestroyed;
            newOptions.afterAdd = options.afterAdd;
            newOptions.beforeRemove = options.beforeRemove;
        } else {
            newOptions.foreach = valueAccessor();
        }

        //use an afterRender function to add meta-data
        if (options.afterRender) {
            //wrap the existing function, if it was passed
            newOptions.afterRender = function (element, data) {
                ko.bindingHandlers.sortableList.afterRender.call(data, element, data);
                options.afterRender.call(data, element, data);
            }
        } else {
            newOptions.afterRender = ko.bindingHandlers.sortableList.afterRender;
        }
        //call the actual template binding
        ko.bindingHandlers.template.update(element, function () { return newOptions; }, allBindingsAccessor, data, context);
    },
    afterRender: function (elements, data) {
        ko.utils.arrayForEach(elements, function (element) {
            if (element.nodeType === 1) {
                $(element).data("sortItem", data);
                $(element).data("parentList", $(element).parent().data("sortList"));
            }
        });
    }
};

ko.bindingHandlers.tinymce = {
    init: function (element, valueAccessor, allBindingsAccessor, context) {
        var options = allBindingsAccessor().tinymceOptions || {};
        var modelValue = valueAccessor();
        var value = ko.utils.unwrapObservable(valueAccessor());
        var el = $(element)

        //handle edits made in the editor. Updates after an undo point is reached.
        options.setup = function (ed) {
            ed.onChange.add(function (ed, l) {
                if (ko.isWriteableObservable(modelValue)) {
                    modelValue(l.content);
                }
            });
        };

        //handle destroying an editor 
        ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
            setTimeout(function () { $(element).tinymce().remove() }, 0)
        });

        setTimeout(function () { $(element).tinymce(options); }, 0);
        el.html(value);

    },
    update: function (element, valueAccessor, allBindingsAccessor, context) {
        var el = $(element)
        var value = ko.utils.unwrapObservable(valueAccessor());
        var id = el.attr('id')

        //handle programmatic updates to the observable
        // also makes sure it doesn't update it if it's the same. 
        // otherwise, it will reload the instance, causing the cursor to jump.
        if (id !== undefined) {
            var content = tinyMCE.getInstanceById(id).getContent({ format: 'raw' })
            if (content !== value) {
                el.html(value);
            }
        }
    }
};


//Validation

function HasErrors() {
    var errors = $('.validationMessage:visible').length;

    if (errors > 0) {
        alert('Please correct ' + errors + ' errors!');
        return true;
    }
    else {
        return false;
    }
}

ko.extenders.required = function (target, overrideMessage) {
    //add some sub-observables to our observable
    target.hasError = ko.observable();
    target.validationMessage = ko.observable();

    //define a function to do validation
    function validate(newValue) {

        if (IsNullOrWhitespace(newValue)) {
            target.hasError(true);
            target.validationMessage(overrideMessage || "This field is required");          
        }
        else {
            target.validationMessage("");
            target.hasError(false);       
        }
           
    }

    //initial validation
    validate(target());

    //validate whenever the value changes
    target.subscribe(validate);

    //return the original observable
    return target;
};


ko.extenders.urlElement = function (target, overrideMessage) {
    //add some sub-observables to our observable
    target.hasError = ko.observable();
    target.validationMessage = ko.observable();

    //define a function to do validation
    function validate(newValue) {

        if (IsCorrectedUrlElement(newValue)) {
            target.hasError(true);
            var errorMessage = overrideMessage || "Please, enter a valid name";
            target.validationMessage(target.validationMessage() + "\n" + errorMessage);
        }
        else {
            target.validationMessage("");
            target.hasError(false);
        }

    }

    //initial validation
    validate(target());

    //validate whenever the value changes
    target.subscribe(validate);

    //return the original observable
    return target;
};


